<?php

class AliPay
{
    //支付宝
    private $AppId = '';
    private $RsaPrivateKey = '';
    private $AlipayrsaPublicKey = '';
    private $NotifyUrl = '';

    public function __construct($alipay)
    {
        $this->AppId = $alipay['appId'];
        $this->RsaPrivateKey = $alipay['rsaPrivateKey'];
        $this->AlipayrsaPublicKey = $alipay['alipayrsaPublicKey'];
        $this->NotifyUrl = $alipay['notifyUrl'];
        require_once str_replace('public', "plugins/alipay/AopSdk.php", getcwd());
    }

    /**
     * 支付宝APP支付
     * @param $subject 标题
     * @param $money 金额
     * @param $order_title 订单号标题
     * @param $order_title 0默认APP支付  1WAP支付
     * @return alipay_sdk 支付宝sdk
     * @return order_no 订单号
     */
    public function aliPay($subject, $money, $out_trade_no, $product_code = 0)
    {
        $path = BASE_PATH . "plugins/alipay";
        $aop = new \AopCertClient;
        $appCertPath = "{$path}/appCertPublicKey_2021002161657132.crt";
        $alipayCertPath = "{$path}/alipayCertPublicKey_RSA2.crt";
        $rootCertPath = "{$path}/alipayRootCert.crt";
        $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";
        $aop->appId = $this->AppId;
        $aop->rsaPrivateKey = $this->RsaPrivateKey;
        $aop->format = "json";
        $aop->charset= "UTF-8";
        $aop->signType= "RSA2";
//是否校验自动下载的支付宝公钥证书，如果开启校验要保证支付宝根证书在有效期内
        $aop->isCheckAlipayPublicCert = true;
//调用getPublicKey从支付宝公钥证书中提取公钥
        $aop->alipayrsaPublicKey = $aop->getPublicKey($alipayCertPath);
//调用getCertSN获取证书序列号
        $aop->appCertSN = $aop->getCertSN($appCertPath);
//调用getRootCertSN获取支付宝根证书序列号
        $aop->alipayRootCertSN = $aop->getRootCertSN($rootCertPath);
        $arr['body'] = $subject;
        $arr['subject'] = $subject;
        $arr['out_trade_no'] = $out_trade_no;
        $arr['timeout_express'] = '30m';
        $arr['total_amount'] = floatval($money);
        if ($product_code == 1) {
            $arr['product_code'] = 'QUICK_WAP_WAY';
        }
        $json = json_encode($arr);
        $request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数，这里只需要传入业务参数
        $request->setBizContent($json);
        $request->setNotifyUrl($this->NotifyUrl);
//这里和普通的接口调用不同，使用的是sdkExecute
        $response = $aop->sdkExecute($request);
//htmlspecialchars是为了输出到页面时防止被浏览器将关键参数html转义，实际打印到日志以及http传输不会有这个问题
        $res['alipayurl'] = $response;
        return $res;
    }


    /**
     * 订单查询接口
     */
    public function search_order_sn($out_trade_no)
    {
        $aop = new AopClient ();
        $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
        $aop->appId = $this->AppId;
        $aop->rsaPrivateKey = $this->RsaPrivateKey;
        $aop->alipayrsaPublicKey = $this->AlipayrsaPublicKey;
        $aop->apiVersion = '1.0';
        $aop->signType = 'RSA2';
        $aop->postCharset = 'UTF-8';
        $aop->format = 'json';
        $request = new AlipayTradeQueryRequest ();
        $data['out_trade_no'] = $out_trade_no;
        $json = json_encode($data);
        $request->setBizContent($json);
        $result = $aop->execute($request);
        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;
        if (!empty($resultCode) && $resultCode == 10000) {
            echo "成功";
        } else {
            echo "失败";
        }
    }

    /**
     * 支付宝提现
     * @param $money
     * @param $alipay_account 支付宝账号
     * @param $real_name 名称
     * @param $remark 备注
     * @param $order_no 订单title
     * @return bool|SimpleXMLElement
     * @throws Exception
     */
    public function oilwithdraw($money, $alipay_account, $real_name, $remark, $title)
    {
        $aop = new AopClient ();
        $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
        $aop->appId = $this->AppId;
        $aop->rsaPrivateKey = $this->RsaPrivateKey;
        $aop->alipayrsaPublicKey = $this->AlipayrsaPublicKey;
        $aop->apiVersion = '1.0';
        $aop->signType = 'RSA2';
        $aop->postCharset = 'UTF-8';
        $aop->format = 'json';
        $request = new AlipayFundTransToaccountTransferRequest ();

        $arr['out_biz_no'] = $this->get_order_no($title);
        $arr['payee_type'] = 'ALIPAY_LOGONID';
        $arr['payee_account'] = $alipay_account;
        $arr['amount'] = floatval($money);
        $arr['payee_real_name'] = $real_name;
        $arr['remark'] = $remark;
        $json = json_encode($arr);
        $request->setBizContent($json);
        $result = $aop->execute($request);
        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;

        $res['order_no'] = $arr['out_biz_no'];
        $res['sub_msg'] = '提现申请提交成功！';
        $res['success'] = true;
        if (empty($resultCode) || $resultCode != 10000) {
            $res['success'] = false;
            $res['sub_msg'] = $result->$responseNode->sub_msg;
        }
        return $res;
    }


    /**
     * 验签
     * @param $parm
     * @return bool
     */
    public function RsaCheckV1($parm)
    {
        unset($parm['_url']);
        $aop = new AopCertClient();
//证书路径
        $path = APP_PATH . "app/plugins/alipay";
        $alipayCertPath = "{$path}/alipayCertPublicKey_RSA2.crt";
//支付宝公钥赋值
        $aop->alipayrsaPublicKey = $aop->getPublicKey($alipayCertPath);
//编码格式
        $aop->postCharset="UTF-8";
//签名方式
        $sign_type="RSA2";
//验签代码
        $flag = $aop->rsaCheckV1($parm, null, $sign_type);
        if ($flag) {
            if ($parm['trade_status'] == 'TRADE_SUCCESS' || $parm['trade_status'] == 'TRADE_FINISHED') {
                return true;
            }
        }
        return false;
    }


    /**
     * 支付宝退款
     * @param $money
     * @param $out_trade_no 订单号
     * @param $subject 备注
     * @return bool|SimpleXMLElement
     * @throws Exception
     */
    public function refund($money, $out_trade_no, $subject)
    {
        $aop = new AopClient ();
        $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
        $aop->appId = $this->AppId;
        $aop->rsaPrivateKey = $this->RsaPrivateKey;
        $aop->alipayrsaPublicKey = $this->AlipayrsaPublicKey;
        $aop->apiVersion = '1.0';
        $aop->signType = 'RSA2';
        $aop->postCharset = 'UTF-8';
        $aop->format = 'json';
        $request = new AlipayTradeRefundRequest ();

        $arr = [
            'out_trade_no' => $out_trade_no,
            'refund_amount' => $money,
            'refund_reason' => $subject,
        ];
        $json = json_encode($arr);
        $request->setBizContent($json);
        $result = $aop->execute($request);
        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;

        if (!empty($resultCode) && $resultCode == 10000) {
            return ['code' => true, 'msg' => '退款成功'];
        } else {
            return ['code' => false, 'msg' => $result->$responseNode->sub_msg];
        }
    }

    /**
     * 单笔转账
     */
    public function withdraw($money, $alipay_account, $real_name, $remark, $title)
    {
        $path = APP_PATH . "app/plugins/alipay";

        $aop = new \AopCertClient;
//        $appCertPath = "应用证书路径（要确保证书文件可读），例如：/home/admin/cert/appCertPublicKey.crt";
//        $alipayCertPath = "支付宝公钥证书路径（要确保证书文件可读），例如：/home/admin/cert/alipayCertPublicKey_RSA2.crt";
//        $rootCertPath = "支付宝根证书路径（要确保证书文件可读），例如：/home/admin/cert/alipayRootCert.crt";
        $appCertPath = "{$path}/appCertPublicKey_2021002161657132.crt";
        $alipayCertPath = "{$path}/alipayCertPublicKey_RSA2.crt";
        $rootCertPath = "{$path}/alipayRootCert.crt";
        $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";
        $aop->appId = $this->AppId;
        $aop->rsaPrivateKey = $this->RsaPrivateKey;
        $aop->format = "json";
        $aop->charset = "UTF-8";
        $aop->signType = "RSA2";
        //调用getPublicKey从支付宝公钥证书中提取公钥
        $aop->alipayrsaPublicKey = $aop->getPublicKey($alipayCertPath);
        //是否校验自动下载的支付宝公钥证书，如果开启校验要保证支付宝根证书在有效期内
        $aop->isCheckAlipayPublicCert = true;
        //调用getCertSN获取证书序列号
        $aop->appCertSN = $aop->getCertSN($appCertPath);
        //调用getRootCertSN获取支付宝根证书序列号
        $aop->alipayRootCertSN = $aop->getRootCertSN($rootCertPath);
        $request = new AlipayFundTransUniTransferRequest ();
        $arr['out_biz_no'] = $this->get_order_no($title);
        $arr['payee_type'] = 'ALIPAY_LOGONID';
        $arr['trans_amount'] = $money;
        $arr['product_code'] = "TRANS_ACCOUNT_NO_PWD";
        $arr['biz_scene'] = "DIRECT_TRANSFER";
        $arr['payee_info'] = [
            "identity" => $alipay_account,
            "identity_type" => "ALIPAY_LOGON_ID",
            "name" => $real_name
        ];
        $arr['remark'] = $remark;
        $json = json_encode($arr);
        $request->setBizContent($json);
        $result = $aop->execute($request);
        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;

        $res['order_no'] = $arr['out_biz_no'];
        $res['sub_msg'] = '提现申请提交成功！';
        $res['success'] = true;
        if (empty($resultCode) || $resultCode != 10000) {
            $res['success'] = false;
            $res['sub_msg'] = $result->$responseNode->sub_msg;
        }
        return $res;

    }


    /**
     * 生成订单号
     * @param $title
     * @return string
     */
    private function get_order_no($title)
    {
        $str = date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
        return $title . $str;
    }

}
